#include <EventListener.hpp>

using namespace DARV;

EventListener::EventListener(Ogre::RenderWindow* win, Ogre::Camera* cam):mWindow(win),mCamera(cam)
{
	initOIS();
	mKeyboard = static_cast<OIS::Keyboard*>(mInputManager->createInputObject( OIS::OISKeyboard, true ));
	mMouse = static_cast<OIS::Mouse*>(mInputManager->createInputObject( OIS::OISMouse, true ));
	/* Enregistrer mKeyboard et mMouse respectivement en tant que KeyListener et MouseListener */
	mKeyboard->setEventCallback(this);
	mMouse->setEventCallback(this);

	moveUp = 0;
	moveDown = 0;
	moveRight = 0;
	moveLeft = 0;
}

EventListener::~EventListener()
{
	mKeyboard->setEventCallback(0);
	mMouse->setEventCallback(0);
	closeOIS();
}

bool EventListener::process(void)
{
	mKeyboard->capture();
	mMouse->capture();

	if (moveUp)
		//mCamera->moveRelative(Ogre::Vector3( 0.0, 0.1, 0.0));
		mCamera->moveRelative(Ogre::Vector3( 0.0, 0.0,-0.1));

	if (moveDown)
		//mCamera->moveRelative(Ogre::Vector3( 0.0,-0.1, 0.0));
		mCamera->moveRelative(Ogre::Vector3( 0.0, 0.0, 0.1));

	if (moveRight)
		mCamera->moveRelative(Ogre::Vector3( 0.1, 0.0, 0.0));

	if (moveLeft)
		mCamera->moveRelative(Ogre::Vector3(-0.1, 0.0, 0.0));

	return true;
}

/**********************************************************************
 KEY LISTENER
*/

bool EventListener::keyPressed(const OIS::KeyEvent &e)
{
	switch (e.key)
	{
		case OIS::KC_ESCAPE:
			std::cout << "Esc" << std::endl;
			return false;
		break;

		case OIS::KC_UP:		moveUp = 1;			break;
		case OIS::KC_DOWN:		moveDown = 1;		break;
		case OIS::KC_RIGHT:		moveRight = 1;		break;
		case OIS::KC_LEFT:		moveLeft = 1;		break;

		default:
			return false;
	}

	return true;
}

bool EventListener::keyReleased(const OIS::KeyEvent &e)
{
	switch (e.key)
	{
		case OIS::KC_UP:		moveUp = 0;			break;
		case OIS::KC_DOWN:		moveDown = 0;		break;
		case OIS::KC_RIGHT:		moveRight = 0;		break;
		case OIS::KC_LEFT:		moveLeft = 0;		break;
		
		default:
			return false;
	}

	return true;
}

/**********************************************************************
 MOUSE LISTENER
*/

bool EventListener::mouseMoved(const OIS::MouseEvent &arg)
{
	mouseX = arg.state.X.abs;
	mouseY = arg.state.Y.abs;
	mCamera->yaw(Ogre::Degree(-arg.state.X.rel * 0.13));
	mCamera->pitch(Ogre::Degree(-arg.state.Y.rel * 0.13));
//	std::cout << mouseX << " " << mouseY << std::endl;
	return true;
}

bool EventListener::mousePressed(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
{
	return true;
}

bool EventListener::mouseReleased(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
{
	switch (id)
	{
		case OIS::MB_Left:
			mouseX = arg.state.X.abs;
			mouseY = arg.state.Y.abs;
		break;

		default:
			return true;
	}

	return true;
}

/*********************************************************************/

/** PRIVATE **/

void EventListener::initOIS(void)
{
	Ogre::LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***");
	OIS::ParamList pl;
	std::ostringstream windowHndStr;
	size_t windowHnd = 0;
	mWindow->getCustomAttribute("WINDOW", &windowHnd);
	windowHndStr << windowHnd;
	pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
	mInputManager = OIS::InputManager::createInputSystem(pl);
}

void EventListener::closeOIS(void)
{
	if (mInputManager)
	{
		mInputManager->destroyInputObject( mMouse );			mMouse = 0;
		mInputManager->destroyInputObject( mKeyboard ); 		mKeyboard = 0;
		OIS::InputManager::destroyInputSystem(mInputManager);	mInputManager = 0;
	}
}
